/*
 *  Copyright (C) 2011 glauco
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.balisunrise.bindings;

import java.util.logging.Level;
import org.balisunrise.application.Application;
import org.balisunrise.common.ConverterException;
import org.balisunrise.common.Event;
import org.balisunrise.common.FieldInput;
import org.balisunrise.common.listeners.FieldInputListener;

/**
 *
 * @author glauco
 */
public class FieldInputTrigger implements FieldInputListener,
        BindingTrigger{

    private FieldInput fieldInput;
    private Binding binding;
    private int fire;
    private Object oldValue;
    private boolean requestFire;

    public FieldInputTrigger(FieldInput fieldInput, Binding binding, 
            int fire) {

        if(fieldInput == null)
            throw new RuntimeException("Erro ao criar um SwingComponentTrigger."
                    + " O FieldInput é nulo.");
        
        if(binding == null)
            throw new RuntimeException("Erro ao criar um SwingComponentTrigger."
                    + " O Binding é nulo.");

        this.fieldInput = fieldInput;
        this.binding = binding;
        this.fire = fire;
        this.oldValue = null;
        this.requestFire = true;
    }

    private void fire(){

        if(binding == null)
            return ;
        
        switch (fire) {
            case BindingPropertyListener.SOURCE:
                binding.sourcePropertyChanged();
                break;
            case BindingPropertyListener.TARGET:
                binding.targerPropertyChanged();
            default:
                return ;
        }

        requestFire = false;
    }

    //
    // FieldInputListener
    //

    @Override
    public void valueChanged(Event evt) { }

    @Override
    public void gotFocus(Event evt) {
        oldValue = fieldInput.getValue();
    }

    @Override
    public void lostFocus(Event evt) { }

    @Override
    public void focusTraversal(Event evt) {

        if(requestFire)
            fire();
        
        Object newValue = fieldInput.getValue();

        Object converted = null;
        try{
            converted = fieldInput.getComponentManager()
                    .getConverter(true).convertReverse(newValue);
        }catch(ConverterException ex){
            Application.get().getLogger().log(Level.FINE, ex.getMessage(), ex);
        }

        if((oldValue == null || newValue == null || converted == null) ||
                (oldValue != null && !oldValue.equals(newValue)))
            fire();
    }

    @Override
    public void afterSync(Event evt) {
        requestFire = true;
    }

    //
    // BindingTrigger
    //

    @Override
    public void activate() {
        fieldInput.addFieldInputListener(this);
        requestFire = true;
    }

    @Override
    public void deactivate() {
        fieldInput.removeFieldInputListener(this);
    }

}
